using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Globalization;
using System.Resources;

namespace WinSSHMenu
{
    public partial class WinSSHMenuPreferences : Form
    {

        public WinSSHMenuPreferences()
        {
            InitializeComponent();
        }

        private void btnUp_Click(object sender, EventArgs e)
        {
            if (null != HostList.SelectedNode)
            {
                moveNode(HostList, Constants.ACTION_MOVEUP);
            }
        }

        private void btnDown_Click(object sender, EventArgs e)
        {
            if (null != HostList.SelectedNode)
            {
                moveNode(HostList, Constants.ACTION_MOVEDOWN);
            }
        }

        private void btnAddHost_Click(object sender, EventArgs e)
        {
            TreeNode selectedNode = HostList.SelectedNode;
            if (null == selectedNode)
            {
                selectedNode = HostList.Nodes[0];
            }

            if (selectedNode.Tag.Equals(Constants.TYPE_SUBMENU) ||
                selectedNode.Tag.Equals(Constants.TYPE_ROOTNODE))
            {
                HostConfig hostConfig = new HostConfig();
                hostConfig.HostList = HostList;
                hostConfig.Action = Constants.ACTION_CREATE;
                hostConfig.ShowDialog();
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnAddSeparator_Click(object sender, EventArgs e)
        {
            TreeNode parentNode = GetParentNode(HostList);
            TreeNode sepNode = new TreeNode();
            sepNode.Text = Constants.SEPERATOR_TEXT;
            sepNode.Tag = Constants.TYPE_SEPARATOR;
            parentNode.Nodes.Add(sepNode);
        }

        private void btnAddSubmenu_Click(object sender, EventArgs e)
        {
            TreeNode parentNode = GetParentNode(HostList);
            if (parentNode.Tag.Equals(Constants.TYPE_SUBMENU) ||
                parentNode.Tag.Equals(Constants.TYPE_ROOTNODE))
            {
                Submenu subMenu = new Submenu();
                subMenu.ParentNode = parentNode;
                subMenu.Action = Constants.ACTION_CREATE;
                subMenu.ShowDialog();
            }
        }

        private void btnEdit_Click(object sender, EventArgs e)
        {
            if (!HostList.SelectedNode.Tag.Equals(Constants.TYPE_ROOTNODE))
            {
                TreeNode parentNode = GetParentNode(HostList);

                // Find out which dialog to show, host edit or submenu edit.
                if (HostList.SelectedNode.Tag.Equals(Constants.TYPE_SUBMENU))
                {
                    Submenu subMenu = new Submenu();
                    subMenu.ParentNode = parentNode;
                    subMenu.txtSubmenuName.Text = HostList.SelectedNode.Text;
                    subMenu.Action = Constants.ACTION_EDIT;
                    subMenu.ShowDialog();
                }
                else
                {
                    HostConfig hostConfig = new HostConfig();
                    hostConfig.HostList = HostList;
                    hostConfig.txtTitle.Text = HostList.SelectedNode.Text;
                    hostConfig.txtHostname.Text =
                        HostList.SelectedNode.Tag.ToString();
                    hostConfig.Action = Constants.ACTION_EDIT;
                    hostConfig.ShowDialog();
                }
            }
        }             

        private void btnCopyHost_Click(object sender, EventArgs e)
        {
            // TODO:  Implement host copy
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            HostList.Nodes.Remove(HostList.SelectedNode);
            HostList.SelectedNode = null;
        }




        private void WinSSHMenuPreferences_Load(object sender, EventArgs e)
        {
            // Load the width and height from the config.
            this.Width = Properties.Settings.Default.WindowWidth;
            this.Height = Properties.Settings.Default.WindowHeight;

            FileUtil util = new FileUtil();
            util.LoadServerList(HostList);

            txtPuttyExe.Text = util.PuttyExe;

            HostList.BeginUpdate();
            if (HostList.Nodes.Count == 0)
            {
                TreeNode rootNode = new TreeNode();
                rootNode.Text = "Server List";
                rootNode.Tag = Constants.TYPE_ROOTNODE;
                rootNode.EnsureVisible();
                HostList.Nodes.Add(rootNode);
            }
            HostList.Nodes[0].ImageIndex = 6;
            HostList.Nodes[0].SelectedImageIndex = 6;
            HostList.Nodes[0].Expand();
            HostList.EndUpdate();
            HostList.Update();

            this.SetApplicationInfo();
        }

        private void SetApplicationInfo()
        {
            this.lblProductName.Text = 
                String.Format("Product Name: {0}", AssemblyProduct);
            this.lblVersion.Text = 
                String.Format("Version: {0}", AssemblyVersion);
            this.lblCopyright.Text = 
                String.Format("Copyright {0}", AssemblyCopyright);
            this.lblCompanyName.Text = AssemblyCompany;
            this.txtDescription.Text = AssemblyDescription;
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            FileUtil util = new FileUtil();
            util.SaveServerList(HostList);
            this.SaveSettings();
            this.Close();
        }

        private void SaveSettings()
        {
            // Save the width and height
            Properties.Settings.Default.WindowWidth = this.Width;
            Properties.Settings.Default.WindowHeight = this.Height;
            Properties.Settings.Default.PuttyPath = this.txtPuttyExe.Text;
            Properties.Settings.Default.Save();
            
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            txtPuttyExe.Text = openFileDialog1.FileName;
        }

        private void HostList_AfterSelect(object sender, TreeViewEventArgs e)
        {
            btnEdit.Enabled = true;
            btnRemove.Enabled = true;
            btnDown.Enabled = true;
            btnUp.Enabled = true;
            btnCopyHost.Enabled = true;
            btnRemove.Enabled = true;
            btnAddHost.Enabled = true;
            btnAddSubmenu.Enabled = true;
            btnAddSeparator.Enabled = true;

            if (HostList.SelectedNode.Tag.Equals(Constants.TYPE_ROOTNODE))
            {
                btnRemove.Enabled = false;
                btnEdit.Enabled = false;
                btnCopyHost.Enabled = false;
                btnUp.Enabled = false;
                btnDown.Enabled = false;

            }
            else if (HostList.SelectedNode.Tag.Equals(Constants.TYPE_SUBMENU))
            {
                // Disable the copy host feature since it only applies to hosts
                btnCopyHost.Enabled = false;

                // Set the correct icon
                HostList.SelectedNode.SelectedImageIndex = 0;

                // Only allow remove for non empty nodes
                if (HostList.SelectedNode.Nodes.Count > 0)
                {
                    btnRemove.Enabled = false;
                }
            }
            else
            {
                // This is a host entry, disable add host, add submenu, and
                // add separater
                btnAddHost.Enabled = false;
                btnAddSeparator.Enabled = false;
                btnAddSubmenu.Enabled = false;
            }
        }


        private void HostList_MouseUp(object sender, MouseEventArgs e)
        {
            // If they click off of the treeview, unselect any 
            // selected node.
            TreeNode thisNode = HostList.GetNodeAt(e.X, e.Y);
            if (null == thisNode)
            {
                HostList.SelectedNode = null;

                // Also disable the actions that require an item to operate
                btnRemove.Enabled = false;
                btnEdit.Enabled = false;
                btnCopyHost.Enabled = false;
                btnUp.Enabled = false;
                btnDown.Enabled = false;
            }
        }

        private void btnExpandAll_Click(object sender, EventArgs e)
        {
            HostList.ExpandAll();
        }

        private void btnCollapseAll_Click(object sender, EventArgs e)
        {
            HostList.CollapseAll();
        }

        private void moveNode(TreeView hostList, String direction)
        {
            // Clone the current node
            TreeNode selectedNode = (TreeNode)hostList.SelectedNode;
            TreeNode parentNode = selectedNode.Parent;

            TreeNode newNode = (TreeNode)selectedNode.Clone();
            int curPos = selectedNode.Index;
            int newPos = curPos;

            if (direction.Equals(Constants.ACTION_MOVEDOWN))
            {
                newPos = curPos + 1;
            }
            else
            {
                newPos = curPos - 1;
            }
            // Remove the current node
            parentNode.Nodes.RemoveAt(curPos);

            //now add the new one
            parentNode.Nodes.Insert(newPos, newNode);
            hostList.SelectedNode = newNode;
        }

        private TreeNode GetParentNode(TreeView hostList)
        {
            TreeNode selectedNode = hostList.SelectedNode;

            if (null == selectedNode)
            {
                selectedNode = hostList.Nodes[0];
            }
            else if (hostList.SelectedNode.Tag.Equals(Constants.TYPE_ROOTNODE))
            {
                selectedNode = hostList.Nodes[0];                
            }
            return selectedNode;
        }

        private void tabAbout_Click(object sender, EventArgs e)
        {

        }

        private void lblProductName_Click(object sender, EventArgs e)
        {

        }

        #region Assembly Attribute Accessors

        public string AssemblyTitle
        {
            get
            {
                // Get all Title attributes on this assembly
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
                // If there is at least one Title attribute
                if (attributes.Length > 0)
                {
                    // Select the first one
                    AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
                    // If it is not an empty string, return it
                    if (titleAttribute.Title != "")
                        return titleAttribute.Title;
                }
                // If there was no Title attribute, or if the Title attribute was the empty string, return the .exe name
                return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
            }
        }

        public string AssemblyVersion
        {
            get
            {
                return Assembly.GetExecutingAssembly().GetName().Version.ToString();
            }
        }

        public string AssemblyDescription
        {
            get
            {
                // Get all Description attributes on this assembly
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
                // If there aren't any Description attributes, return an empty string
                if (attributes.Length == 0)
                    return "";
                // If there is a Description attribute, return its value
                return ((AssemblyDescriptionAttribute)attributes[0]).Description;
            }
        }

        public string AssemblyProduct
        {
            get
            {
                // Get all Product attributes on this assembly
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
                // If there aren't any Product attributes, return an empty string
                if (attributes.Length == 0)
                    return "";
                // If there is a Product attribute, return its value
                return ((AssemblyProductAttribute)attributes[0]).Product;
            }
        }

        public string AssemblyCopyright
        {
            get
            {
                // Get all Copyright attributes on this assembly
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
                // If there aren't any Copyright attributes, return an empty string
                if (attributes.Length == 0)
                    return "";
                // If there is a Copyright attribute, return its value
                return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
            }
        }

        public string AssemblyCompany
        {
            get
            {
                // Get all Company attributes on this assembly
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
                // If there aren't any Company attributes, return an empty string
                if (attributes.Length == 0)
                    return "";
                // If there is a Company attribute, return its value
                return ((AssemblyCompanyAttribute)attributes[0]).Company;
            }
        }
        #endregion

        private void WinSSHMenuPreferences_Closing(object sender, FormClosingEventArgs e)
        {
            this.SaveSettings();
        }

        private void LinkPutty_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("IExplore", Properties.Settings.Default.PuttyLink);
        }

        private void VisitSiteLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("IExplore", Properties.Settings.Default.SiteLink);
        }

        private void btnImportBrowse_Click(object sender, EventArgs e)
        {
            importFileDialog.ShowDialog();
        }

        private void importFileDialog_FileOK(object sender, CancelEventArgs e)
        {
            txtImport.Text = importFileDialog.FileName;
            btnImport.Enabled = true;
        }

        private void btnImport_Click(object sender, EventArgs e)
        {
            if (txtImport.Text.Length == 0)
            {
                btnImport.Enabled = false;
                MessageBox.Show("You must first specify a file to import");
            }
            else
            {
                // Make sure they really want to replace their server list
                DialogResult dlgResult =
                    MessageBox.Show("Are you sure you want to replace your " +
                                "existing server list with the one located " +
                                "at " + txtImport.Text + " ?",
                                "Import Server List?",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dlgResult == DialogResult.Yes)
                {
                    // First make a backup copy of the original file,
                    // then copy in the new one.
                    FileUtil fu = new FileUtil();
                    if (txtImport.Text == fu.AppPath)
                    {
                        MessageBox.Show(
                            "Sorry you cannot import the current server list");
                    }
                    else
                    {
                        fu.ReplaceServerList(txtImport.Text);
                        String BaseAppDir =
                            fu.AppDir + "\\" + 
                            Properties.Settings.Default.AppDir + "\\";
                        MessageBox.Show(
                            "Server list has been replaced. \n" +
                            "A backup copy was placed in the " + BaseAppDir +
                            " folder");

                        HostList.Nodes.Clear();
                        fu.LoadServerList(HostList);
                        HostList.Update();
                        HostList.Nodes[0].Expand();   
                    }            
                }
            }
        }

        private void HostList_DoubleClick(object sender, EventArgs e)
        {
            // We only want to launch actual host list entries.
            if(HostList.SelectedNode.Tag.ToString().
                Equals(Constants.TYPE_SUBMENU) ||
               HostList.SelectedNode.Tag.ToString().
                Equals(Constants.TYPE_SEPARATOR) || 
               HostList.SelectedNode.Tag.ToString().
                Equals(Constants.TYPE_ROOTNODE))
            {
                return;
            }

            FileUtil util = new FileUtil();
            util.LaunchSSHProcess(HostList.SelectedNode.Tag.ToString(), 
                                  HostList.SelectedNode.Text);
        }
    }
}
